package backing;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.servlet.http.HttpSession;

import to.Cidade;
import to.Email;
import to.Endereco;
import to.Estado;
import to.Laboratorio;
import to.Lancamento;
import to.Pessoa;
import to.SolicitacaoDeAnalise;
import to.Telefone;
import to.Usuario;
import util.CommonsMail;
import util.JSFUtil;
import DAO.AbstractDAO;
import DAO.CidadeDAO;
import DAO.EmailDAO;
import DAO.EnderecoDAO;
import DAO.EstadoDAO;
import DAO.FuncionarioDAO;
import DAO.PessoaDAO;
import DAO.TelefoneDAO;
import DAO.UsuarioDAO;

@ManagedBean
@ViewScoped
public class PessoaBacking implements Serializable {
	private static final long serialVersionUID = 1L;

	private Pessoa pessoaSalvar = new Pessoa();
	private Endereco enderecoSalvar = new Endereco();
	private Usuario usuarioSalvar = new Usuario();
	private to.Email emSalvar = new to.Email();
	private Telefone foneSalvar = new Telefone();

	private Integer estadoSalvar;
	private Integer cidadeSalvar;

	private String cpfPesquisa;
	private String senhaSalvar;

	private DataModel<Pessoa> listaPessoa;
	private List<Lancamento> listaLancamentosDoCliente;
	private List<SolicitacaoDeAnalise> listaSolicitacaoDoCliente;
	private List<Email> listaEmail;
	private List<Telefone> listaTelefone;

	private Boolean tipoPessoaSalvar = true;

	private String mascara = "999.999.999-99";
	private String txtCpf = "CPF: (*)";;

	private Pessoa pessoaSelecionada;

	private ArrayList<Estado> listaEstados;
	private ArrayList<Cidade> listaCidades;

	UsuarioDAO usuarioDAO = new UsuarioDAO();
	EstadoDAO estadoDAO = new EstadoDAO();
	EnderecoDAO enderecoDAO = new EnderecoDAO();
	CidadeDAO cidadeDAO = new CidadeDAO();
	AbstractDAO abstractDAO = new AbstractDAO();
	PessoaDAO pessoaDAO = new PessoaDAO();
	EmailDAO emDAO = new EmailDAO();
	TelefoneDAO foneDAO = new TelefoneDAO();

	public void delete() {
		try {
			if (pessoaSelecionada.getCodigo() != 0) {
				abstractDAO.delete(pessoaSelecionada);
				JSFUtil.addInfoMessage("Deletado com sucesso!");
			} else {
				JSFUtil.addInfoMessage("Erro ao Deletar");
			}
		} catch (Exception e) {

			e.printStackTrace();
		}
	}

	public void carregarPessoas() {
		try {
			this.listaPessoa = new ListDataModel<Pessoa>(pessoaDAO.buscaTodos());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void trocarMascara() {

		if (tipoPessoaSalvar) {
			mascara = "999.999.999-99";
			txtCpf = "CPF: (*)";
		} else {
			txtCpf = "CNPJ: (*)";
			mascara = "99.999.999/9999-99";
		}
	}

	public void carregarPessoa() {

		try {
			Pessoa busca = pessoaDAO.pesquisarCPF(pessoaSalvar.getCpf_cnpj());
			System.out.println(pessoaSalvar.getNome() + " - "
					+ pessoaSalvar.getEndereco().getLogadouro());
			if (busca != null) {
				System.out.println("not nulllllllllllllllllllll");
				tipoPessoaSalvar = busca.getTipoPessoa();
				this.trocarMascara();
				pessoaSalvar = busca;
				enderecoSalvar = busca.getEndereco();
				this.carregarEstados();
				estadoSalvar = enderecoSalvar.getCidade().getEstado()
						.getCodigo();
				cidadeSalvar = enderecoSalvar.getCidade().getCodigo();
				this.carregarCidades();
				usuarioSalvar = busca.getUsuario();
				senhaSalvar = busca.getUsuario().getSenha();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void preparaAlteracao(Pessoa p) {

		pessoaSelecionada = p;
		
		if (pessoaSelecionada != null) {

			tipoPessoaSalvar = pessoaSelecionada.getTipoPessoa();
			this.trocarMascara();
			pessoaSalvar = pessoaSelecionada;
			enderecoSalvar = pessoaSelecionada.getEndereco();
			this.carregarEstados();
			estadoSalvar = enderecoSalvar.getCidade().getEstado().getCodigo();
			this.carregarCidades();
			cidadeSalvar = enderecoSalvar.getCidade().getCodigo();

			criaListaSolicitacao();
			criaListaLancamento();
			criaListaEmail();
			criaListaTelefone();
		}
	}

	public void salvarPessoa() {
		try {

			pessoaSalvar.setTipoPessoa(tipoPessoaSalvar);
			abstractDAO.saveOrUpdate(pessoaSalvar);

			JSFUtil.addInfoMessage("Cliente salvo com sucesso!");

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void salvarEndereco() {

		try {

			enderecoSalvar.setCidade(cidadeDAO
					.buscarCidadePorCodigo(cidadeSalvar));
			pessoaSalvar.setEndereco(enderecoSalvar);
			abstractDAO.saveOrUpdate(pessoaSalvar);

		} catch (Exception e) {
			e.printStackTrace();
		}
		enderecoSalvar = null;
		enderecoSalvar = new Endereco();
	}

	public void salvarTelefone() {

		try {

			foneSalvar.setPessoa(pessoaSalvar);
			abstractDAO.saveOrUpdate(foneSalvar);
			criaListaTelefone();

		} catch (Exception e) {
			e.printStackTrace();
		}
		foneSalvar = null;
		foneSalvar = new Telefone();
	}

	public void salvarEmail() {

		try {

			emSalvar.setPessoa(pessoaSalvar);
			abstractDAO.saveOrUpdate(emSalvar);
			criaListaEmail();

		} catch (Exception e) {
			e.printStackTrace();
		}
		emSalvar = null;
		emSalvar = new Email();
	}

	public void enviarEmail() {

		try {
			ExternalContext externalContext = FacesContext.getCurrentInstance()
					.getExternalContext();
			HttpSession session = (HttpSession) externalContext
					.getSession(true);
			Usuario usuario = (Usuario) session.getAttribute("currentUser");
			Laboratorio laboratorio = new FuncionarioDAO()
					.pesquisarFuncionarioUsuario(usuario).getLaboratorio();
			new CommonsMail().emailPessoa(laboratorio, pessoaSalvar);
			JSFUtil.addInfoMessage("E-mail eviado com sucesso.");
		} catch (Exception e) {
			e.printStackTrace();
		}
		this.reset();
	}

	public void reset() {

		tipoPessoaSalvar = true;
		mascara = "999.999.999-99";
		estadoSalvar = null;
		cidadeSalvar = null;
		usuarioSalvar = null;
		senhaSalvar = null;
		pessoaSelecionada = null;

		pessoaSalvar = new Pessoa();
		enderecoSalvar = new Endereco();
		usuarioSalvar = new Usuario();

		carregarEstados();
		listaCidades = null;

	}

	@PostConstruct
	public void carregarEstados() {
		try {
			listaEstados = (ArrayList<Estado>) estadoDAO.buscaTodos();
		} catch (Exception e) {
			JSFUtil.addInfoMessage("ERRO AO CARREGAR ESTADOS");
		}
	}

	public void carregarCidades() {
		System.out.println("Cidades CArregadas");
		try {
			listaCidades = (ArrayList<Cidade>) cidadeDAO
					.pesquisarCidadesPorEstado(estadoSalvar);
		} catch (Exception e) {
			JSFUtil.addInfoMessage("ERRO AO CARREGAR CIDADES");
		}
	}

	public void criaListaEmail() {

		System.out.println("To chegando com o ID: " + pessoaSalvar.getCodigo());

		this.listaEmail = new ArrayList<>(
				emDAO.buscaEmailPorPessoa(pessoaSalvar.getCodigo()));

	}

	public void criaListaTelefone() {

		this.listaTelefone = new ArrayList<>(
				foneDAO.buscaFonePorPessoa(pessoaSalvar.getCodigo()));

	}

	public void criaListaSolicitacao() {

		try {

			this.listaSolicitacaoDoCliente = new ArrayList<SolicitacaoDeAnalise>(
					pessoaDAO.buscarSolicitacaoPessoa(pessoaSelecionada));

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void criaListaLancamento() {

		try {

			this.listaLancamentosDoCliente = new ArrayList<Lancamento>(
					pessoaDAO.buscarTodosPorPessoa(pessoaSelecionada));

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public Pessoa getPessoaSalvar() {
		return pessoaSalvar;
	}

	public void setPessoaSalvar(Pessoa pessoaSalvar) {
		this.pessoaSalvar = pessoaSalvar;
	}

	public Endereco getEnderecoSalvar() {
		return enderecoSalvar;
	}

	public void setEnderecoSalvar(Endereco enderecoSalvar) {
		this.enderecoSalvar = enderecoSalvar;
	}

	public Usuario getUsuarioSalvar() {
		return usuarioSalvar;
	}

	public void setUsuarioSalvar(Usuario usuarioSalvar) {
		this.usuarioSalvar = usuarioSalvar;
	}

	public Integer getEstadoSalvar() {
		return estadoSalvar;
	}

	public void setEstadoSalvar(Integer estadoSalvar) {
		this.estadoSalvar = estadoSalvar;
	}

	public Integer getCidadeSalvar() {
		return cidadeSalvar;
	}

	public void setCidadeSalvar(Integer cidadeSalvar) {
		this.cidadeSalvar = cidadeSalvar;
	}

	public String getCpfPesquisa() {
		return cpfPesquisa;
	}

	public void setCpfPesquisa(String cpfPesquisa) {
		this.cpfPesquisa = cpfPesquisa;
	}

	public DataModel<Pessoa> getListaPessoa() {
		return listaPessoa;
	}

	public void setListaPessoa(DataModel<Pessoa> listaPessoa) {
		this.listaPessoa = listaPessoa;
	}

	public Boolean getTipoPessoaSalvar() {
		return tipoPessoaSalvar;
	}

	public void setTipoPessoaSalvar(Boolean tipoPessoaSalvar) {
		this.tipoPessoaSalvar = tipoPessoaSalvar;
	}

	public String getMascara() {
		return mascara;
	}

	public void setMascara(String mascara) {
		this.mascara = mascara;
	}

	public String getTxtCpf() {
		return txtCpf;
	}

	public void setTxtCpf(String txtCpf) {
		this.txtCpf = txtCpf;
	}

	public Pessoa getPessoaSelecionada() {
		return pessoaSelecionada;
	}

	public void setPessoaSelecionada(Pessoa pessoaSelecionada) {
		this.pessoaSelecionada = pessoaSelecionada;
	}

	public ArrayList<Estado> getListaEstados() {
		return listaEstados;
	}

	public void setListaEstados(ArrayList<Estado> listaEstados) {
		this.listaEstados = listaEstados;
	}

	public ArrayList<Cidade> getListaCidades() {
		return listaCidades;
	}

	public void setListaCidades(ArrayList<Cidade> listaCidades) {
		this.listaCidades = listaCidades;
	}

	public String getSenhaSalvar() {
		return senhaSalvar;
	}

	public void setSenhaSalvar(String senhaSalvar) {
		this.senhaSalvar = senhaSalvar;
	}

	public List<Lancamento> getListaLancamentosDoCliente() {
		return listaLancamentosDoCliente;
	}

	public void setListaLancamentosDoCliente(
			List<Lancamento> listaLancamentosDoCliente) {
		this.listaLancamentosDoCliente = listaLancamentosDoCliente;
	}

	public List<SolicitacaoDeAnalise> getListaSolicitacaoDoCliente() {
		return listaSolicitacaoDoCliente;
	}

	public void setListaSolicitacaoDoCliente(
			List<SolicitacaoDeAnalise> listaSolicitacaoDoCliente) {
		this.listaSolicitacaoDoCliente = listaSolicitacaoDoCliente;
	}

	public UsuarioDAO getUsuarioDAO() {
		return usuarioDAO;
	}

	public void setUsuarioDAO(UsuarioDAO usuarioDAO) {
		this.usuarioDAO = usuarioDAO;
	}

	public EstadoDAO getEstadoDAO() {
		return estadoDAO;
	}

	public void setEstadoDAO(EstadoDAO estadoDAO) {
		this.estadoDAO = estadoDAO;
	}

	public EnderecoDAO getEnderecoDAO() {
		return enderecoDAO;
	}

	public void setEnderecoDAO(EnderecoDAO enderecoDAO) {
		this.enderecoDAO = enderecoDAO;
	}

	public CidadeDAO getCidadeDAO() {
		return cidadeDAO;
	}

	public void setCidadeDAO(CidadeDAO cidadeDAO) {
		this.cidadeDAO = cidadeDAO;
	}

	public AbstractDAO getAbstractDAO() {
		return abstractDAO;
	}

	public void setAbstractDAO(AbstractDAO abstractDAO) {
		this.abstractDAO = abstractDAO;
	}

	public PessoaDAO getPessoaDAO() {
		return pessoaDAO;
	}

	public void setPessoaDAO(PessoaDAO pessoaDAO) {
		this.pessoaDAO = pessoaDAO;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	public to.Email getEmSalvar() {
		return emSalvar;
	}

	public void setEmSalvar(to.Email emSalvar) {
		this.emSalvar = emSalvar;
	}

	public Telefone getFoneSalvar() {
		return foneSalvar;
	}

	public void setFoneSalvar(Telefone foneSalvar) {
		this.foneSalvar = foneSalvar;
	}

	public List<Email> getListaEmail() {
		return listaEmail;
	}

	public void setListaEmail(List<Email> listaEmail) {
		this.listaEmail = listaEmail;
	}

	public List<Telefone> getListaTelefone() {
		return listaTelefone;
	}

	public void setListaTelefone(List<Telefone> listaTelefone) {
		this.listaTelefone = listaTelefone;
	}
}
